#!/usr/bin/ruby
# -*- coding: utf-8 -*-
#require "rubygems"
require "opengl"
require "glut"
require "m3g"
require "pp"
require "values"

# 注意: 回転はクォータニオンで指定するが、
# M3Gで定義されていないQuaternionクラスはRuby側に公開していない。
# 来的にはRubyから使えるようにするかも。
# q0 = [ 0,0,0.382683, 0.92388 or 45 ,0,0,1 ]
# q1 = [ -0,-0,-0.382683, 0.92388 or 45 ,-0,-0,-1 ]
# q2 = [ 0,0,0.382683, 0.92388 or 45 ,0,0,1 ]

class MyGLUTWidget
  def initialize
    GLUT.Init
    GLUT.InitWindowSize  256, 256
    GLUT.InitDisplayMode GLUT::GLUT_DOUBLE | GLUT::GLUT_RGB | GLUT::GLUT_DEPTH
    GLUT.CreateWindow "Ruby-M3G"

    initialize_scene

    GLUT.ReshapeFunc  method(:reshape).to_proc()
    GLUT.DisplayFunc  method(:display).to_proc()
    GLUT.KeyboardFunc method(:keyboard).to_proc()
    GLUT.MouseFunc    method(:mouse).to_proc()
    GLUT.IdleFunc     method(:idle).to_proc()
  end

  def initialize_scene

    keyframe_sequence    = M3G::KeyframeSequence.new  3, 4, M3G::KeyframeSequence::SLERP
    keyframe_orientation = [[0,0,0.382683,  0.92388],  # 45, 0,0,1
                            [0,0,-0.382683, 0.92388],  # 45, 0,0,-1
                            [0,0,0.382683,  0.92388]]  # 45, 0,0,1
    keyframe_sequence.keyframe[0] = 0, keyframe_orientation[0]
    keyframe_sequence.keyframe[1] = 100, keyframe_orientation[1]
    keyframe_sequence.keyframe[2] = 200, keyframe_orientation[2]
    keyframe_sequence.repeat_mode = M3G::KeyframeSequence::LOOP
    keyframe_sequence.valid_range = 0, 2
    keyframe_sequence.duration    = 200

    animation_controller = M3G::AnimationController.new
    animation_track     = M3G::AnimationTrack.new keyframe_sequence, M3G::AnimationTrack::ORIENTATION
    animation_track.controller = animation_controller

    positions = M3G::VertexArray.new 42, 3, 2
    positions.values[0,42] = $position_values
    
    scale = 0.001
    bias  = [0,0,0]

    vertices = M3G::VertexBuffer.new
    vertices.positions = positions, scale, bias

    strips = [42]
    tris = M3G::TriangleStripArray.new 0, strips
    
    app = M3G::Appearance.new

    bone0 = M3G::Group.new
    bone1 = M3G::Group.new
    bone1.translate 0,10,0
    bone0.child << bone1

    mesh = M3G::SkinnedMesh.new vertices, tris, app, bone0

    mesh.bone_transform << [bone0, 10, 0, 18]
    mesh.bone_transform << [bone0, 8 , 18, 2]
    mesh.bone_transform << [bone0, 6 , 20, 2]
    mesh.bone_transform << [bone0, 4 , 22, 2]
    mesh.bone_transform << [bone0, 2 , 24, 2]
    mesh.bone_transform << [bone1, 2 , 18, 2]
    mesh.bone_transform << [bone1, 4 , 20, 2]
    mesh.bone_transform << [bone1, 6 , 22, 2]
    mesh.bone_transform << [bone1, 8 , 24, 2]
    mesh.bone_transform << [bone1, 10, 26, 16]
    
    bone1.post_rotate 90, 0,0,1
    bone1.animation_track << animation_track
    
    cam = M3G::Camera.new
    cam.translate 0,10,50
    
    @wld = M3G::World.new
    @wld.child << cam
    @wld.child << mesh
    @wld.active_camera = cam

    @world_time = 0
  end

  def reshape width, height
    g3d = M3G::Graphics3D::instance
    g3d.viewport = 0,0,width,height
    @wld.active_camera.perspective = 45, width/(height*1.0), 0.1, 100
  end

  def display
    g3d = M3G::Graphics3D::instance
    g3d.render @wld
    GLUT.SwapBuffers()
  end
  
  def keyboard key, x, y
    if key == 113  # 'q'
      exit
    elsif key == 32 # ' '
      @wld.animate @world_time
      @world_time += 5
    end
    GLUT.PostRedisplay
  end

  def mouse button, state, x, y
  end

  def idle
    GLUT.PostRedisplay
  end

  def start
    GLUT.MainLoop
  end

end


MyGLUTWidget.new.start

